package com.lucky.passport.service.impl;

import com.alibaba.fastjson.JSON;
import com.lucky.passport.controller.SMSController;
import com.lucky.passport.mapper.UserInfoMapper;
import com.lucky.passport.mapper.UsersMapper;
import com.lucky.passport.ex.ServiceException;
import com.lucky.passport.pojo.dto.LoginDTO;
import com.lucky.passport.pojo.dto.UsersAddNewDTO;
import com.lucky.passport.pojo.entity.UserInfo;
import com.lucky.passport.pojo.entity.Users;
import com.lucky.passport.pojo.vo.UserInfoListItemVO;
import com.lucky.passport.pojo.vo.UserInfoStandardVO;
import com.lucky.passport.pojo.vo.UsersStandardVO;
import com.lucky.passport.security.CommonUserDetails;
import com.lucky.passport.service.IUsersService;
import com.lucky.passport.web.ServiceCode;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;

import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@Transactional
public class UsersServiceImpl implements IUsersService {
    @Autowired
    PasswordEncoder passwordEncoder;
    @Autowired
    UsersMapper usersMapper;
    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    AuthenticationManager authenticationManager;
    @Value("${csmall.jwt.secret-key}")
    String secretKey;

    @Value("${csmall.jwt.duration-in-minute}")
    long durationInMinute;

    @Override
    public int updateById(UserInfo userInfo) {
        userInfoMapper.updateById(userInfo);
        return 0;
    }

    @Override
    public UserInfoStandardVO selectById(Long id) {
        UserInfoStandardVO userInfoStandardVO = userInfoMapper.selectById(id);
        return userInfoStandardVO;
    }

    @Override
    public void addNew(UsersAddNewDTO usersAddNewDTO){
        log.debug("即将处理注册用户业务");

        String username = usersAddNewDTO.getUsername();
        int count = usersMapper.countByUsername(username);
        System.out.println(count);
        if(count!=0){
            String message = "注册用户失败，尝试添加的用户名已存在!";
            throw new ServiceException(ServiceCode.ERR_INSERT,message);
        }
        usersAddNewDTO.setRole("普通用户");
        Users users = new Users();
        BeanUtils.copyProperties(usersAddNewDTO,users);
        usersMapper.insert(users);
        //获取已添加到users表用户的数据
        UsersStandardVO standardVO = usersMapper.getByUsername(username);
        users.setId(standardVO.getId());
        //插入成功
        userInfoMapper.insert(users);
    }

    @Override
    public void delete(Long id) {
        log.debug("开始处理【删除用户请求】");
        usersMapper.delete(id);
        userInfoMapper.delete(id);
    }

    @Override
    public String login(LoginDTO loginDTO) {
        log.info("开始处理[登录]的请求");
        Authentication authentication
                = new UsernamePasswordAuthenticationToken(
                loginDTO.getUsername(), loginDTO.getPassword());
        Authentication authenticateResult
                = authenticationManager.authenticate(authentication);
        log.debug("执行认证成功，AuthenticationManager返回：{}", authenticateResult);
        Object principal = authenticateResult.getPrincipal();
        log.debug("认证结果中的Principal数据类型：{}", principal.getClass().getName());
        log.debug("认证结果中的Principal数据：{}", principal);
        CommonUserDetails adminDetails = (CommonUserDetails) principal;

        log.debug("准备生成JWT数据");
        Map<String, Object> claims = new HashMap<>();
        claims.put("id", adminDetails.getId()); // 向JWT中封装id
        claims.put("username", adminDetails.getUsername()); // 向JWT中封装username
        claims.put("nick",adminDetails.getNick());
        claims.put("authorities", JSON.toJSONString(adminDetails.getAuthorities())); // 向JWT中封装权限

        Date expirationDate = new Date(System.currentTimeMillis() + durationInMinute * 60 * 1000);
        String jwt = Jwts.builder()
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                .setClaims(claims)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        log.debug("返回JWT数据：{}", jwt);
        return jwt;
    }

    @Override
    public List<UserInfoListItemVO> list() {
        log.debug("开始处理【查询用户信息列表】");
       return userInfoMapper.list();
    }



}
